package ssi.cameraTest;

import android.app.Activity;
import android.graphics.Region;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.FrameLayout;
import android.widget.TextView;

public class CameraTest extends Activity implements SensorEventListener {
	CustomCameraView cv;
	public static SensorManager sensorMan;
	private static final int matrix_size = 16;
	float[] R = new float[matrix_size];
	float[] outR = new float[matrix_size];
	float[] I = new float[matrix_size];
	float[] values = new float[3];
	private float[] mags;
	private float[] accels;
	private float azimuth;
	private float oldAzimuth;
	private Object pitch;
	private Object roll;
	private static double lat1 = 41.951035;
	private static double lon1 = 12.519385;
	private static double lat2 = 42.091035;
	private static double lon2 = 12.619385;
	private float incValue;
	private float inclination;
	private float oldInclination=0;
	private float minInclination=360;
	private float maxInclination=0;
	private double bearDegree;
	private double skew = 1.0;
	private int width;
	private int height;
	private PalloccoView point;
	private Activity ctx;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(ssi.cameraTest.R.layout.main);
        sensorMan = (SensorManager) getSystemService(SENSOR_SERVICE);
        cv = new CustomCameraView(getApplicationContext());
        Display disp = getWindowManager().getDefaultDisplay();
        width = disp.getWidth();
        height = disp.getHeight();
        FrameLayout rl = (FrameLayout)findViewById(ssi.cameraTest.R.id.ARMainLayout);
        ctx = this;
        sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
		sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
		point = new PalloccoView(getApplicationContext());
		point.setAuthor("Giuseppe");
		point.setSubject("Prova subject");
		point.setActivity(this);
		point.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		point.setLocation((float)width/2, (float)height/2, 1.0f);
		point.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return ((PalloccoView)v).touchEvent(event);
			}
		});
        rl.addView(cv, width, height);
        rl.addView(point);
        oldAzimuth = 0;
        bearDegree = GeoTest.bearing(lat1, lon1, lat2, lon2);
    }
    
	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
	}
	
	@Override
	public void onSensorChanged(SensorEvent event) {
	if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
		return;
		switch (event.sensor.getType()) {
		case Sensor.TYPE_MAGNETIC_FIELD:
		mags = event.values.clone();
		break;
		case Sensor.TYPE_ACCELEROMETER:
		accels = event.values.clone();
		break;
		}

		if (mags != null && accels != null) {
			SensorManager.getRotationMatrix(R, I, accels, mags);

			// Correct if screen is in Landscape
			SensorManager.remapCoordinateSystem(R,SensorManager.AXIS_X,SensorManager.AXIS_Z, outR);

			SensorManager.getOrientation(outR, values);
			incValue=SensorManager.getInclination(I);
			azimuth = (float) Math.round((Math.toDegrees(values[0]))*7)/7;
//          Adjust the range: 0 < range <= 360 (from: -180 < range <= 180).
            azimuth = ( azimuth + 360)%360; // alternative: mAzimuth = mAzimuth>=0 ? mAzimuth : mAzimuth+360;
            
            //inclination = (float) Math.round((Math.toDegrees(incValue))*2)/2;
            //inclination = (inclination + 180)%180;
            //if (Math.abs(oldInclination - inclination)>3){
//            tv.setText("Azimuth (deg)= " + azimuth);
//            tv.append("\n Azimuth (rad)= " + values[0]);
//            inclination=-Math.round((float) (values[1]*(360/(2*Math.PI))));
//            tv.append("\n Pitch (rad)= " + values[1]);
//            tv.append("\n Pitch (deg)= " + inclination);
//            tv.append("\n Roll (rad)= " + (values[2]*(360/(2*Math.PI))));
            //tv.append("\n Inclination(deg) = " + inclination);
            //tv.append("\n Inclination(rad) = " + incValue);
            //tv.append("\n MAX Inclination(deg) = " + maxInclination);
            //tv.append("\n MIN Inclination(deg) = " + minInclination);
            //System.out.println("Inclination: " + inclination);
			//System.out.println("Azimuth: " + azimuth);
			//oldInclination=inclination;
			//minInclination = (inclination > minInclination)?minInclination:inclination;
			//maxInclination = (inclination<maxInclination)?maxInclination:inclination;
            //}
//			azimuth = Convert.radToDeg(values[0]);
//			pitch = Convert.radToDeg(values[1]);
//			roll = Convert.radToDeg(values[2]);
			if (Math.abs((azimuth-oldAzimuth)) > skew) {
				oldAzimuth = azimuth;
				refreshView();
			}
		}
	}
	
	public void scaleUp(PalloccoView target) {
		sensorMan.unregisterListener(this);
		float targetWidth = target.getX_length()*2;
		float scaleFactor = Math.round((width/targetWidth) - 1.0f);
		target.setLocation(width/2, height/2, 1.0f);
		ScaleAnimation animation = new ScaleAnimation(
				1.0f, scaleFactor, 
				1.0f, scaleFactor, 
				Animation.ABSOLUTE, (float)width/2, 
				Animation.ABSOLUTE, (float)height/2);
		animation.setInterpolator(ctx, android.R.anim.accelerate_interpolator);
		animation.setDuration(500);
		animation.setFillAfter(true);
		animation.willChangeBounds();
		animation.willChangeTransformationMatrix();
		target.startAnimation(animation);
		target.touch();
		target.setScale(scaleFactor);
		//sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
		//sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
	}
	
	private void refreshView() {
		double cameraAngle = 30.0;
		double result = cameraAngle/2 + (bearDegree - azimuth);
		double left_arm = azimuth - cameraAngle/2;
		double right_arm = azimuth + cameraAngle/2;
		if (!(result > right_arm || result < left_arm)) {
			float x_value = (float)(result/cameraAngle)*width;
			float x = Math.round(x_value);
			System.out.println("\nSposto il pallocco in posizione x=" + x);
			point.setLocation(x, (float)height/2, 1.0f);
		}
	}
	
	@Override
	protected void onStop() {
		sensorMan.unregisterListener(this);
		super.onStop();
	}
}